package com.yang.http

import android.util.Log
import com.google.gson.JsonObject
import com.yang.http.bean.IBaseResponse
import com.yang.http.bean.entityCodeNullable
import com.yang.http.bean.entityNullable
import com.yang.http.bean.msgEntityCodeNullable
import com.yang.http.bean.msgEntityNullable
import com.yang.http.bean.notHttpException
import org.json.JSONObject
import retrofit2.HttpException

object HttpHandler {
    /**
     * 处理请求结果
     *
     * [entity] 实体
     * [onSuccess] 状态码对了就回调
     * [onResult] 状态码对了，且实体不是 null 才回调
     * [onFailed] 有错误发生，可能是服务端错误，可能是数据错误，详见 code 错误码和 msg 错误信息
     */
    fun <T> handleResult(
        entity: IBaseResponse<T?>?,
        onResult: ((t: T) -> Unit),
        onFailed: ((code: Int, message: String?) -> Unit)? = null
    ) {
        // 防止实体为 null
        if (entity == null) {
            onFailed?.invoke(entityNullable, msgEntityNullable)
            return
        }
        val code = entity.code()
        val message = entity.message()
        // 防止状态码为 null
        if (code == null) {
            onFailed?.invoke(entityCodeNullable, msgEntityCodeNullable)
            return
        }
        // 请求成功
        if (entity.isSuccess()) {
            // 实体不为 null 才有价值
            entity.data()?.let { onResult.invoke(it) }
        } else {
            // 失败了
            onFailed?.invoke(code, message)
        }
    }

    /**
     * 处理异常
     */
    fun handleException(
        e: Exception,
        onFailed: (code: Int, message: String?) -> Unit
    ) {
//        Log.e("请求失败：", " 结果是：${e.toString()}")
        if (e is HttpException) {
            try {
                val httpResult = JSONObject(e.response()?.errorBody()?.string())

//                Log.e("请求失败：", " httpResult 结果是：${httpResult}")

                if (null != httpResult) {
                    if (420 == e.code() || 400 == e.code()|| 401 == e.code()) {
                        return onFailed(e.code(), decodeUnicode(httpResult.getString("message")))
                    }
                } else {
//                    Log.e("请求失败：", " httpResult为空 解析失败")
                }
            } catch (ex: java.lang.Exception) {
//                Log.e("请求失败：", " 解析失败 结果是：${ex.toString()}")
            }
        }
        return onFailed(notHttpException, "请求太快了，请休息下~~")
    }


    fun decodeUnicode(unicodeStr: String): String {
        val sb = StringBuilder()
        var i = -1
        var pos = 0
        while (unicodeStr.indexOf("\\u", pos).also { i = it } != -1) {
            sb.append(unicodeStr, pos, i)
            if (i + 5 < unicodeStr.length) {
                pos = i + 6
                val c = unicodeStr.substring(i + 2, i + 6).toInt(16).toChar()
                sb.append(c)
            }
        }
        sb.append(unicodeStr.substring(pos))
        return sb.toString()
    }

    /**
     * 处理请求结果
     *
     * [entity] 实体
     * [onSuccess] 状态码对了就回调
     * [onResult] 状态码对了，且实体不是 null 才回调
     * [onFailed] 有错误发生，可能是服务端错误，可能是数据错误，详见 code 错误码和 message 错误信息
     */
    fun handleResultString(
        entity: JsonObject?,
        onResult: ((t: JsonObject) -> Unit),
        onFailed: ((code: Int, message: String?) -> Unit)? = null
    ) {
        // 防止实体为 null
        if (entity == null) {
            onFailed?.invoke(entityNullable, msgEntityNullable)
            return
        }
        // 回调成功
        entity?.let {
            onResult.invoke(it)
        }
    }

    /**
     * 处理请求结果
     *
     * [entity] 实体
     * [onSuccess] 状态码对了就回调
     * [onResult] 状态码对了，且实体不是 null 才回调
     * [onFailed] 有错误发生，可能是服务端错误，可能是数据错误，详见 code 错误码和 msg 错误信息
     */
    fun handleResultString(
        entity: Any?,
        onResult: ((t: Any) -> Unit),
        onFailed: ((code: Int, message: String?) -> Unit)? = null
    ) {
        // 防止实体为 null
        if (entity == null) {
            onFailed?.invoke(entityNullable, msgEntityNullable)
            return
        }
        // 回调成功
        entity?.let {
            onResult.invoke(it)
        }
    }
}